/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author jefoutta
 */

import java.util.*;

public class Protoboard {
    public static LinkedHashMap<String,LogicGate> logicGates = new LinkedHashMap();
    public static LinkedHashMap<String,Source> sources = new LinkedHashMap();
    public static LinkedList<String> logicGatesList = new LinkedList();
    public static LinkedList<String> sourcesList = new LinkedList();
    private  HashMap<String,Integer> logicGatesTypes;
    public static LinkedList<Connection> connections = new LinkedList();
    public static String currentSource;

    public Protoboard(){
        logicGatesTypes = new HashMap();
        logicGatesTypes.put("AND", 1);
        logicGatesTypes.put("OR", 2);
        logicGatesTypes.put("NOT", 3);
        logicGatesTypes.put("NAND", 4);
        logicGatesTypes.put("NOR", 5);
    }

    public void addLogicGate(String type, String name, int entries){
        type = type.toUpperCase();
        int option = logicGatesTypes.get(type);
        switch (option){
            case 1: {
                logicGates.put(name, new And(name,entries));
                logicGatesList.add(name);
            }
            break;
            case 2:{
                logicGates.put(name, new Or(name,entries));
                logicGatesList.add(name);
            }
            break;
            case 3:{
                logicGates.put(name, new Not(name));
                logicGatesList.add(name);
            }
        }
    }

    public void addSource(String id){
        sources.put(id, new Source(id));
        sourcesList.add(id);
    }

    public void addConnection(String source, String destiny){
        this.connections.addLast(new Connection());
        if(this.logicGates.containsKey(source)){
            this.connections.getLast().conect(this.logicGates.get(source), this.logicGates.get(destiny));
        }
        if(this.sources.containsKey(source)){
            this.connections.getLast().conect(this.sources.get(source), this.logicGates.get(destiny));
        }
    }

    public static void reset(){
        for(int i = 0; i < Protoboard.logicGatesList.size(); i++){
            Protoboard.logicGates.get(Protoboard.logicGatesList.get(i)).reset();
        }
        for(int i = 0; i < Protoboard.sourcesList.size(); i++){
            Protoboard.sources.get(Protoboard.sourcesList.get(i)).reset();
        }
        LogicGate.bigError = false;
    }

    public static void completeReset(){
        for(int i = 0; i < Protoboard.logicGatesList.size(); i++){
            Protoboard.logicGates.get(Protoboard.logicGatesList.get(i)).completeReset();
        }
        for(int i = 0; i < Protoboard.sourcesList.size(); i++){
            Protoboard.sources.get(Protoboard.sourcesList.get(i)).reset();
        }
        LogicGate.bigError = false;
    }

    public void findTruePaths(){
        for(int i = 0; i < this.sourcesList.size(); i++){
            this.currentSource = this.sourcesList.get(i);
            System.out.println(this.currentSource+"!!!!!!!!!!!!!!!!!!!!!!");
            do{
                this.sources.get(this.sourcesList.get(i)).sensitize();
            }while(this.sources.get(this.sourcesList.get(i)).pathCount != 0);
            this.completeReset();
        }
    }

    @Override
    public String toString(){
        String s = "";
        s = s + this.sources.toString()+"\n\n";
        s = s + this.logicGates.toString();
        return s;
    }
}
